<template>
  <view class="content">
    <view class="text-container" v-if="!showEditor">
      <h1>抖音丛林迷宫</h1>
      <view>
        <button @click="chooseFile">选择文件</button>
        <button id="btn_edit" @click="openEditor">编辑地图</button>
      </view>
      
      <!-- 文件内容展示区域 -->
      <view style="margin-top: 15px;">
        json数据内容：<br>
        <textarea id="json_content" v-model="jsonContent"></textarea>
      </view>
      <button id="btn_solve" @click="btnsolve">解决</button>
      <!-- 结果内容展示区域 -->
      <view style="margin-top: 15px;">
        结果内容：<br>
        <textarea id="result_content" v-model="resultContent" readonly></textarea>
        <view style="margin-top: 10px;">
          <button id="prev_result" @click="showPreviousResult">&lt;</button>
          <button id="next_result" @click="showNextResult">&gt;</button>
        </view>
      </view>
    </view>
    
    <!-- 地图编辑器区域 -->
    <view class="editor-container" v-else>
      <h1>丛林迷宫编辑器</h1>
      <button @click="backToMain">返回主页面</button>
      
      <!-- 设置区域 -->
      <div class="settings">
        <h3>网格设置</h3>
        <div>
          <label for="grid-width">宽度:</label>
          <input type="number" id="grid-width" v-model.number="gridWidth" min="3" max="20">
          <label for="grid-height">高度:</label>
          <input type="number" id="grid-height" v-model.number="gridHeight" min="3" max="20">
          <label for="step-limit">步数限制:</label>
          <input type="number" id="step-limit" v-model.number="stepLimit" min="1">
          <button @click="createGrid">创建网格</button>
          <button @click="clearAllObstacles" style="background-color: #f44336;">清除所有障碍物</button>
        </div>
      </div>
      
      <!-- 图符选择区域 -->
      <div class="tile-selection">
        <h3>选择图符:</h3>
        <div class="tile-buttons">
          <button class="tile-btn" :class="{ selected: currentValue === '0' }" @click="selectTile('0')">0</button>
          <button class="tile-btn" :class="{ selected: currentValue === '1' }" @click="selectTile('1')">1</button>
          <button class="tile-btn" :class="{ selected: currentValue === '*' }" @click="selectTile('*')">*</button>
          <button class="tile-btn" :class="{ selected: currentValue === 'A' }" @click="selectTile('A')">A 蜗牛</button>
          <button class="tile-btn" :class="{ selected: currentValue === 'B' }" @click="selectTile('B')">B 蜘蛛</button>
          <button class="tile-btn" :class="{ selected: currentValue === 'C' }" @click="selectTile('C')">C 蚂蚱</button>
          <button class="tile-btn" :class="{ selected: currentValue === 'D' }" @click="selectTile('D')">D 瓢虫</button>
          <button class="tile-btn" :class="{ selected: currentValue === 'E' }" @click="selectTile('E')">E 蜜蜂</button>
          <button class="tile-btn" :class="{ selected: currentValue === 'F' }" @click="selectTile('F')">F 蝴蝶</button>
          <button class="tile-btn" :class="{ selected: currentValue === 'G' }" @click="selectTile('G')">G 甲虫</button>
          <button class="tile-btn" :class="{ selected: currentValue === 'obstacle' }" @click="selectTile('obstacle')">障碍</button>
        </div>
      </div>
      
      <!-- 障碍设置提示 -->
      <div class="obstacle-hint" v-if="obstacleMode">
        <strong>提示:</strong> 请点击两个相邻的格子来设置障碍物。您可以在内部格子之间或边界格子与外部之间设置障碍物。
      </div>
      
      <!-- 网格区域 -->
      <div class="grid-wrapper">
        <div class="grid" :style="gridStyle">
          <!-- 顶部虚拟行 -->
          <div v-for="j in gridWidth + 2" :key="'top-' + j" class="virtual-cell" @click="onCellClick(-1, j - 2)"></div>
          
          <!-- 中间行（包含真实格子和两侧虚拟格子） -->
          <template v-for="i in gridHeight" :key="'row-' + i">
            <!-- 左侧虚拟格子 -->
            <div class="virtual-cell" @click="onCellClick(i - 1, -1)"></div>
            
            <!-- 真实格子 -->
            <div 
              v-for="j in gridWidth" 
              :key="'cell-' + i + '-' + j" 
              class="grid-cell" 
              :class="{ 'value-0': getGridCell(i - 1, j - 1) === '0' }"
              @click="onCellClick(i - 1, j - 1)"
            >
              {{ getGridCell(i - 1, j - 1) }}
            </div>
            
            <!-- 右侧虚拟格子 -->
            <div class="virtual-cell" @click="onCellClick(i - 1, gridWidth)"></div>
          </template>
          
          <!-- 底部虚拟行 -->
          <div v-for="j in gridWidth + 2" :key="'bottom-' + j" class="virtual-cell" @click="onCellClick(gridHeight, j - 2)"></div>
        </div>
        
        <!-- 障碍物层 -->
        <div class="obstacle-layer">
          <div 
            v-for="(barrier, index) in barriers" 
            :key="'obstacle-' + index" 
            class="obstacle-line" 
            :class="getObstacleClass(barrier)"
            :style="getObstacleStyle(barrier)"
          ></div>
        </div>
      </div>
      
      <!-- 障碍物列表 -->
      <div class="obstacle-list">
        <h3>障碍物列表:</h3>
        <div v-if="barriers.length === 0" style="color: #999;">暂无障碍物</div>
        <div v-for="(barrier, index) in barriers" :key="index" class="obstacle-item">
          障碍 {{index + 1}}: {{formatCoord(barrier[0], barrier[1])}} - {{formatCoord(barrier[2], barrier[3])}}
          <button class="remove-obstacle" @click="removeObstacle(index)">移除</button>
        </div>
      </div>
      
      <!-- 操作按钮 -->
      <button @click="generateJson" style="margin-top: 10px;">生成JSON并返回</button>
    </view>
  </view>
</template>

<script>
  // 导入必要的工具文件
  import { bfsAsync, setBfsMaxLoop } from './../../utils/bfsAsync.js'
  import { ClmgFactory } from './../../utils/clmg.js'
  
  export default {
    data() {
      return {
        title: '抖音丛林迷宫',
        jsonContent: '',
        resultContent: '',
        traceResults: [],
        resultIndex: 0,
        // 编辑器相关数据
        showEditor: false,
        gridWidth: 5,
        gridHeight: 5,
        stepLimit: 20,
        currentValue: '1', // 默认值为1（绿地）
        obstacleMode: false,
        obstacleFirstCell: null, // 存储第一个选中的格子坐标
        gridData: [],
        barriers: [],
        cellSize: 40, // 统一为40px，与CSS一致
        borderSize: 2, // 网格间距
        padding: 5, // 网格内边距
        debugLog: '' // 调试日志字符串
      }
    },
    // 添加watch监听器，监测网格尺寸变化
    watch: {
      gridWidth(newVal, oldVal) {
        if (newVal !== oldVal && this.showEditor) {
          this.createGrid();
        }
      },
      gridHeight(newVal, oldVal) {
        if (newVal !== oldVal && this.showEditor) {
          this.createGrid();
        }
      }
    },
    computed: {
      gridStyle() {
        return {
          gridTemplateColumns: `repeat(${this.gridWidth + 2}, ${this.cellSize}px)`
        }
      }
    },
    onLoad() {
      // 这里可以添加页面加载时的初始化逻辑
    },
    onShow() {
      // 从本地存储中获取可能保存的地图数据
      try {
        const mapData = uni.getStorageSync('mapEditorData');
        if (mapData) {
          this.jsonContent = mapData;
          // 清除存储的数据
          uni.removeStorageSync('mapEditorData');
        }
      } catch (e) {
        console.error('读取本地存储失败:', e);
      }
    },
    methods: {
      // 选择文件
      chooseFile() {
        // 使用uni-app原生API
        uni.chooseFile({
          count: 1,
          extension: ['json'],
          success: (res) => {
            const tempFilePath = res.tempFilePaths[0];
            try {
              // 使用文件系统管理器读取文件
              const fs = uni.getFileSystemManager ? uni.getFileSystemManager() : null;
              if (fs) {
                fs.readFile({
                  filePath: tempFilePath,
                  encoding: 'utf-8',
                  success: (res) => {
                    this.jsonContent = res.data;
                    // 清空结果内容和索引
                    this.traceResults = [];
                    this.resultIndex = 0;
                    this.resultContent = '';
                  },
                  fail: (err) => {
                    console.error('文件读取失败:', err);
                    uni.showToast({
                      title: '文件读取失败',
                      icon: 'none'
                    });
                  }
                });
              } else {
                uni.showToast({
                  title: '不支持的运行环境',
                  icon: 'none'
                });
              }
            } catch (e) {
              console.error('文件操作异常:', e);
              uni.showToast({
                title: '文件操作异常',
                icon: 'none'
              });
            }
          },
          fail: (err) => {
            console.error('文件选择失败:', err);
          }
        });
      },
      
      // 打开编辑器
      openEditor() {
        this.showEditor = true;
        // 检测是否为移动设备并调整单元格大小
        this.checkMobileAndAdjustSize();
        this.createGrid();
      },
      
      // 返回主页面
      backToMain() {
        this.showEditor = false;
      },
      
      // 检测移动设备并调整单元格大小
      checkMobileAndAdjustSize() {
        // 使用uni.getSystemInfo替代navigator.userAgent
        try {
          const systemInfo = uni.getSystemInfoSync();
          // 根据屏幕宽度判断是否为移动设备
          if (systemInfo.windowWidth <= 600) {
            // 移动设备上使用较小的单元格大小
            this.cellSize = 32;
          }
        } catch (e) {
          console.error('获取系统信息失败:', e);
        }
      },
      
      // 选择图符
      selectTile(value) {
        this.currentValue = value;
        this.obstacleMode = value === 'obstacle';
        // 重置选中状态
        this.obstacleFirstCell = null;
      },
      
      // 获取网格单元格的值
      getGridCell(row, col) {
        if (row >= 0 && row < this.gridHeight && col >= 0 && col < this.gridWidth) {
          return this.gridData[row][col] || '0';
        }
        return '';
      },
      
      // 创建网格 - 包含外围虚拟格子
      createGrid() {
        try {
          if (isNaN(this.gridWidth) || this.gridWidth < 3 || this.gridWidth > 20 || 
              isNaN(this.gridHeight) || this.gridHeight < 3 || this.gridHeight > 20) {
            uni.showToast({
              title: '请输入3-20之间的数字',
              icon: 'none'
            });
            return;
          }
          
          // 初始化网格数据
          this.gridData = [];
          for (let i = 0; i < this.gridHeight; i++) {
            this.gridData[i] = [];
            for (let j = 0; j < this.gridWidth; j++) {
              this.gridData[i][j] = '0'; // 默认为空地
            }
          }
          
          // 重置障碍物
          this.barriers = [];
          this.obstacleFirstCell = null;
        } catch (error) {
          console.error('创建网格时出错:', error);
          uni.showToast({
            title: '创建网格失败',
            icon: 'none'
          });
        }
      },
      
      // 单元格点击事件
      onCellClick(row, col) {
        if (this.obstacleMode) {
          this.handleObstacleSelection(row, col);
        } else {
          // 只处理真实格子（非虚拟格子）
          if (row >= 0 && row < this.gridHeight && col >= 0 && col < this.gridWidth) {
            // 更新单元格值
            this.gridData[row][col] = this.currentValue;
          }
        }
      },
      
      // 判断是否为真实格子
      isRealCell(row, col) {
        return row >= 0 && row < this.gridHeight && col >= 0 && col < this.gridWidth;
      },
      
      // 处理障碍选择 - 支持边界障碍物
      handleObstacleSelection(row, col) {
        if (!this.obstacleFirstCell) {
          // 第一次点击，记录第一个单元格
          this.obstacleFirstCell = { row, col };
        } else {
          // 第二次点击，检查是否都为虚拟格子
          if(!this.isRealCell(row, col) && !this.isRealCell(this.obstacleFirstCell.row, this.obstacleFirstCell.col)){
            uni.showToast({
              title: '请选择至少一个真实的单元格来设置障碍',
              icon: 'none'
            });
          } else {
            // 第二次点击，检查是否相邻
            const firstRow = this.obstacleFirstCell.row;
            const firstCol = this.obstacleFirstCell.col;
            
            // 检查是否相邻（上下左右）
            const isAdjacent = 
              (Math.abs(row - firstRow) === 1 && col === firstCol) || 
              (Math.abs(col - firstCol) === 1 && row === firstRow);
            
            if (isAdjacent) {
              // 添加障碍
              this.barriers.push([firstCol, firstRow, col, row]);
            } else {
              uni.showToast({
                title: '请选择两个相邻的单元格来设置障碍',
                icon: 'none'
              });
            }
          }
          
          // 重置
          this.obstacleFirstCell = null;
        }
      },
      
      // 获取障碍物样式类
      getObstacleClass(barrier) {
        const [c1, r1, c2, r2] = barrier;
        return r1 === r2 ? 'vertical' : 'horizontal';
      },
      
      // 获取障碍物样式
      getObstacleStyle(barrier) {
        const [c1, r1, c2, r2] = barrier;
        
        // 计算实际的位置偏移（考虑虚拟格子）
        const getRealPosition = (row, col) => {
          // 计算实际坐标
          const realRow = row + 1;
          const realCol = col + 1;
          // 计算位置 - 移除垂直方向的额外+2偏移量，保持与水平方向一致
          const left = realCol * (this.cellSize + this.borderSize) + this.padding;
          const top = realRow * (this.cellSize + this.borderSize) + this.padding;
          return { left, top, realRow, realCol };
        };
        
        // 获取两个格子的真实位置
        const pos1 = getRealPosition(r1, c1);
        const pos2 = getRealPosition(r2, c2);
        
        if (r1 === r2) {
          // 垂直方向的障碍（左右相邻的格子）
          const left = Math.max(pos1.left, pos2.left);
          const top = Math.min(pos1.top, pos2.top);
          
          return {
            left: `${left - 2}px`,
            top: `${top}px`
          };
        } else {
          // 水平方向的障碍（上下相邻的格子）
          const left = Math.min(pos1.left, pos2.left);
          const top = Math.max(pos1.top, pos2.top);
          
          return {
            left: `${left}px`,
            top: `${top - 2}px`
          };
        }
      },
      
      // 格式化坐标显示
      formatCoord(row, col) {
        if (row === -1) return `(左界,${col})`;
        if (row === this.gridHeight) return `(右界,${col})`;
        if (col === -1) return `(${row},上界)`;
        if (col === this.gridWidth) return `(${row},下界)`;
        return `(${row},${col})`;
      },
      
      // 移除障碍物
      removeObstacle(index) {
        this.barriers.splice(index, 1);
      },
      
      // 清除所有障碍物
      clearAllObstacles() {
        this.barriers = [];
      },
      
      // 生成JSON数据
      generateJson() {
        try {
          //gridData转换成行字符串列表
          const board = this.gridData.map(row => row.join(''));
          // 生成JSON字符串
          const jsonStr = JSON.stringify({
            width: this.gridWidth,
            height: this.gridHeight,
            board: board,
            barriers: this.barriers,
            step_limit: this.stepLimit
          }, null, 2);
          
          // 将数据保存到主页面的jsonContent
          this.jsonContent = jsonStr;
          
          // 保存到本地存储（以防页面跳转问题）
          uni.setStorageSync('mapEditorData', jsonStr);
          
          // 返回主页面
          this.showEditor = false;
          
          uni.showToast({
            title: '地图数据已生成',
            icon: 'success'
          });
        } catch (e) {
          console.error('生成JSON时出错:', e);
          uni.showToast({
            title: '生成JSON数据失败',
            icon: 'none'
          });
        }
      },
      
      // 解决按钮点击事件
      btnsolve() {
        if (!this.jsonContent) {
          uni.showToast({
            title: '请先输入json数据',
            icon: 'none'
          });
          return;
        }
        
        try {
          // 创建迷宫对象
          const clmg = new ClmgFactory();
          
          // 使用readFromJson方法初始化数据
          if (!clmg.readFromJson(this.jsonContent)) {
            throw new Error('JSON数据格式不正确');
          }
          
          // 重置结果相关数据
          this.traceResults = [];
          this.resultIndex = 0;
          this.resultContent = '';
          
          // 设置最大循环次数
          setBfsMaxLoop(clmg.step_limit * 100);
          
          // 创建终点状态（所有动物都到达目标地的状态）
          const vd = new ClmgFactory();
          vd.CopyFrom(clmg);
          vd.success(); // 将终点设置为成功状态
          
          // 执行BFS算法 - 修复部分
          bfsAsync(clmg, vd, (trace) => {
            if (trace && trace.length > 0) {
              // 提取路径上的每个状态
              this.traceResults = [];
              for (let i = 0; i < trace.length; i++) {
                this.traceResults.push({
                  step: i,
                  board: trace[i].board,
                  width: trace[i].width,
                  height: trace[i].height
                });
              }
              
              if (this.traceResults.length > 0) {
                this.showResult(this.traceResults[this.traceResults.length - 1]);
              }
            } else {
              this.resultContent = '没有找到解决方案';
              uni.showToast({
                title: '没有找到解决方案',
                icon: 'none'
              });
            }
          });
        } catch (error) {
          console.error('JSON解析错误:', error);
          uni.showToast({
            title: 'JSON格式错误: ' + error.message,
            icon: 'none'
          });
        }
      },
      
      // 显示结果
      showResult(result) {
        if (!result) {
          this.resultContent = '无结果';
          return;
        }
        this.resultContent = JSON.stringify(result, null, 2);
      },
      
      // 显示上一个结果
      showPreviousResult() {
        if (this.traceResults.length === 0) return;
        this.resultIndex = (this.resultIndex - 1 + this.traceResults.length) % this.traceResults.length;
        this.showResult(this.traceResults[this.resultIndex]);
      },
      
      // 显示下一个结果
      showNextResult() {
        if (this.traceResults.length === 0) return;
        this.resultIndex = (this.resultIndex + 1) % this.traceResults.length;
        this.showResult(this.traceResults[this.resultIndex]);
      }
    }
  }
</script>

<style>
  /* 全局CSS变量 */
  :root {
    --cell-size: 40px;
  }

    /* 全局样式 */
  body {
    font-family: Arial, sans-serif;
    background-color: #f5f5f5;
    margin: 0;
    padding: 20px;
  }

  .container {
    max-width: 800px;
    margin: 0 auto;
    background-color: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  }

  h1, h2, h3 {
    color: #333;
  }

  /* 设置区域样式 */
  .settings {
    margin-bottom: 20px;
    padding: 15px;
    background-color: #f9f9f9;
    border-radius: 5px;
  }

  .settings input {
    padding: 8px;
    margin-right: 10px;
    border: 1px solid #ccc;
    border-radius: 4px;
  }

  .settings button {
    padding: 8px 15px;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
  }

  /* 图符按钮样式 */
  .tile-buttons {
    margin-bottom: 15px;
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
  }

  .tile-btn {
    min-width: 60px;
    height: 40px;
    padding: 0 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #f5f5f5; /* 浅灰色背景 */
    color: #333; /* 深灰色文字 */
    border: 2px solid #ccc;
    border-radius: 5px;
    cursor: pointer;
    font-size: 14px;
  }

  .tile-btn.selected {
    border-color: #4CAF50;
    background-color: #e8f5e9;
    color: #2e7d32;
  }


  /* 网格样式 */
  .grid-wrapper {
    position: relative;
    display: block;
    width: 100%;
    overflow-x: scroll;
    overflow-y: hidden;
    padding-bottom: 20px;
  }
  
  .grid {
    display: grid;
    gap: 2px;
    background-color: #ddd;
    padding: 5px;
    border-radius: 5px;
    position: relative;
  }
  
  /* 强制显示滚动条的样式 */
  ::-webkit-scrollbar {
    width: 8px;
    height: 8px;
  }

  ::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 4px;
  }
  
  ::-webkit-scrollbar-thumb {
    background: #888;
    border-radius: 4px;
  }
  
  ::-webkit-scrollbar-thumb:hover {
    background: #555;
  }

  /* 网格单元格样式 */
  .grid-cell {
    width: var(--cell-size);
    height: var(--cell-size);
    background-color: #fff;
    border: 1px solid #ccc;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: calc(var(--cell-size) * 0.5);
    cursor: pointer;
    position: relative;
  }

  /* 内容为0的格子背景色（与虚拟单元格相同） */
  .grid-cell.value-0 {
    background-color: #f0f0f0;
  }
  
  .grid-cell:hover {
    background-color: #f0f0f0;
  }
  
  /* 虚拟单元格（用于边界障碍物选择） */
  .virtual-cell {
    width: var(--cell-size);
    height: var(--cell-size);
    background-color: #f0f0f0;
    border: 1px dashed #999;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: calc(var(--cell-size) * 0.3);
    color: #999;
    cursor: pointer;
    position: relative;
  }

  /* 障碍设置提示样式 */
  .obstacle-hint {
    margin-top: 10px;
    padding: 10px;
    background-color: #fff3cd;
    border: 1px solid #ffeaa7;
    border-radius: 5px;
  }

  /* 障碍物可视化样式 */
  .obstacle-layer {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    pointer-events: none;
    z-index: 10;
  }
  
  /* 障碍物线条样式 */
  .obstacle-line {
    position: absolute;
    background-color: #f44336;
    z-index: 10;
    border-radius: 2px;
  }
  
  
  /* 水平障碍物 - 使用CSS变量保持一致 */
  .obstacle-line.horizontal {
    height: 4px;
    width: var(--cell-size);
    background-color: #f44336;
  }
  
  /* 垂直障碍物 - 使用CSS变量保持一致 */
  .obstacle-line.vertical {
    width: 4px;
    height: var(--cell-size);
    background-color: #f44336;
  }
  
  /* 障碍物列表样式 */
  .obstacle-list {
    margin-top: 20px;
    padding: 15px;
    background-color: #f9f9f9;
    border-radius: 5px;
  }

  .obstacle-list h3 {
    margin-top: 0;
    color: #333;
  }

  .obstacle-item {
    padding: 5px 0;
    border-bottom: 1px solid #eee;
  }

  .obstacle-item:last-child {
    border-bottom: none;
  }

  .remove-obstacle {
    background-color: #f44336;
    font-size: 12px;
    padding: 2px 8px;
    margin-left: 10px;
  }

  /* 增加移动设备响应式调整 */
  @media (max-width: 600px) {
    body {
      padding: 10px;
    }
    
    .container {
      padding: 15px;
      border-radius: 5px;
      max-width: 100%;
    }
    
    /* 已经在上面设置了，这里不需要重复 */
    /* .grid-wrapper {
      overflow-x: auto;
      padding-bottom: 10px;
    }
    
    .grid {
      min-width: min-content;
    }
    
    /* 调整按钮和输入框大小 */
    .settings input {
      width: 50px;
      margin-right: 5px;
      margin-bottom: 5px;
    }
    
    .settings button {
      padding: 8px 10px;
      font-size: 14px;
      margin-bottom: 5px;
    }
  }
  
  /* 原有样式 */
  .content {
    padding: 20px;
  }
  
  .text-container {
    max-width: 800px;
    margin: 0 auto;
  }
  
  h1 {
    color: #333;
    text-align: center;
  }
  
  textarea {
    width: 100%;
    height: 200px;
    padding: 10px;
    font-family: monospace;
    font-size: 14px;
    border: 1px solid #ccc;
    border-radius: 5px;
    resize: vertical;
    box-sizing: border-box;
  }
  
  button {
    padding: 8px 16px;
    background-color: #007AFF;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    margin-right: 10px;
    margin-top: 10px;
  }
  
  button:hover {
    background-color: #0056CC;
  }
</style>